package main

import (
	"fmt"
	//"time"
)

type Person struct {
	Name    string
	Age     uint8
	Address Addr
}

type Addr struct {
	city     string
	district string
}

type PersonHandler interface {
	Batch(origs <-chan Person) <-chan Person
	Handle(orig *Person)
}

//类型声明
type PersonHandlerImpl struct{}

func (handler PersonHandlerImpl) Batch(origs <-chan Person) <-chan Person {
	//初始化通道dests
	dests := make(chan Person, 100)

	go func() {
		//需要被更改的人员信息会通过origs单向通道传递进来，那么我们就应该不断的试图从该通道中接收它们。
		for p := range origs {
			//变更人员信息
			handler.Handle(&p)
			//把人员信息发送给通道dests
			dests <- p
		}
		fmt.Println("All the information has been handled.")
		//关闭通道dests
		close(dests)
	}()
	return dests
}

func (handler PersonHandlerImpl) Handle(orig *Person) {
	//处理人员信息
	if orig.Address.district == "Haidian" {
		orig.Address.district = "ShiJingshan"
	}
}

func getPersonHandler() PersonHandler {
	return PersonHandlerImpl{}
}

var personTotal = 200
var persons []Person = make([]Person, personTotal)
var personCount int

func init() {
	//初始化人员信息
	for i := 0; i < personTotal; i++ {
		name := fmt.Sprintf("%s%d", "P", i)
		p := Person{name, 24, Addr{"Beijing", "Haidian"}}
		persons[i] = p
	}
}

func main() {
	handler := getPersonHandler()
	//初始化通道origs
	origs := make(chan Person, 100)
	//启用G2以处理人员信息
	dests := handler.Batch(origs)
	//启用G3以获取人员信息
	fecthPerson(origs)
	//启用G4以存储人员信息
	sign := savePerson(dests)
	<-sign
}

//接受一个参数 是只允许写入origs通道
func fecthPerson(origs chan<- Person) {
	go func() {
		for _, p := range persons {
			origs <- p
		}
		fmt.Println("All the information has been fetched.")
		close(origs)
	}()

}

//接受一个参数 是只允许读取dest通道  除非直接强制转换 要么你只能从channel中读取数据
func savePerson(dest <-chan Person) <-chan byte {
	sign := make(chan byte, 1)
	go func() {
		for {
			p, ok := <-dest
			if !ok {
				fmt.Println("All the information has been saved.")
				sign <- 0
				break
			}
			savePerson1(p)
		}
	}()
	return sign
}

func savePerson1(p Person) bool {
	fmt.Println(p)
	return true
}
